/**
 * 
 */
package com.saas.service.saas;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.DBObject;
import com.saas.dao.MongoCondition;
import com.saas.exception.ServiceException;
import com.saas.service.APIService;
import com.saas.service.AuthorizationService;
import com.saas.service.FunctionsService;
import com.saas.service.VerifyCodeService;
import com.saas.util.*;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author xxb
 *
 */
@Component
public class UserService {

	protected static Logger logger = LoggerFactory.getLogger(UserService.class);
	
	@Autowired
	private APIService apiService;
	@Autowired
	private FunctionsService functionsService;
	@Autowired
	private AuthorizationService authorizationService;
//	@Autowired
//	private CacheService cacheService;
	@Autowired
	private VerifyCodeService verifyCodeService;

	/**
	 * 获取用户头像
	 * getUserIcon:
	 *
	 * @author sid
	 * @param userId
	 * @return
	 * @throws ServiceException 
	 */
	public String getUserIcon(String userId) throws ServiceException {
		JSONObject user = getUserById(userId);
		String iconUrl = user.getString("iconUrl");
		if (!DataUtils.isNotEmpty(iconUrl)) {
			if (user.containsKey("authData")
					&&DataUtils.isNotEmpty(user.getJSONObject("authData"))
					&&user.getJSONObject("authData").containsKey("weixin")
					&&DataUtils.isNotEmpty(user.getJSONObject("authData").getJSONObject("weixin"))
					&&user.getJSONObject("authData").getJSONObject("weixin").containsKey("headimgurl")) {
				iconUrl = user.getJSONObject("authData").getJSONObject("weixin").getString("headimgurl");
			}
		}
		return iconUrl;
	}

	
	public JSONObject register(JSONObject user) throws Exception{
		logger.info("register data:"+user.toString());
		String reqmobilePhoneNumber = user.getString(Constant.user_phonenum);
		String requsername = user.getString(Constant.user_username);
		if("saas".equals(user.getString(Constant.user_site))){
			logger.info(reqmobilePhoneNumber);
			if (StringUtils.isBlank(reqmobilePhoneNumber) || mobilePhoneNumberExists(Constant.model_users,reqmobilePhoneNumber)){
				 return null;
			}else{
				//如果有手机号则直接绑定
				user.put("mobileIsBind", 1);
			}
		}
		String p1 = user.getString(Constant.user_password);
//		String password = new Sha512Hash(p1, Constant.sha512_salt, 513).toBase64();
		String password = Md5Util.encode(p1+requsername);
		user.put(Constant.user_password, password);
		
		JSONObject dbUser = apiService.save(Constant.model_users, user.toJSONString());
		
		JSONObject login = new JSONObject();
		if(!"saas".equals(user.getString(Constant.user_site))){
			login.put(Constant.User_loginIdentifying, requsername);
		}else{
			login.put(Constant.User_loginIdentifying, user.getString(Constant.user_phonenum));
		}
		
		login.put(Constant.user_password, p1);
		login.put(Constant.user_site, user.getString("site"));
		JSONObject loginUser = login(login);
		
		return loginUser;
	}
	
	
	/**
	 * 用户名是否存在
	 * @param username
	 * @return Boolean true存在 false不存在
	 * @throws ServiceException
	 */
	public Boolean usernameExists(String username) throws ServiceException{
		if(StringUtils.isBlank(username)){
			return false;
		}
		DBObject dbusername = apiService.findOneByField(Constant.model_users, "username", username);
		if (dbusername != null) {
			return true;
		}
		return false;
	}
	
	/**
	 * 用户手机号是否存在
	 * @param mobile
	 * @return Boolean true存在 false不存在
	 * @throws ServiceException
	 */
	public boolean mobilePhoneNumberExists(String model,String mobile) throws ServiceException{
		if(StringUtils.isBlank(mobile)){
			return false;
		}
		DBObject dbusername = apiService.findOneByField(model, Constant.user_phonenum, mobile);
		if (dbusername != null) {
			return true;
		}
		return false;
	}
	
	/**
	 * 
	 * 根据手机号查找用户
	 * findUserByMobilePhoneNumber:
	 *
	 * @author sid
	 * @param model
	 * @param mobile
	 * @return
	 * @throws ServiceException
	 */
	public DBObject findUserByMobilePhoneNumber(String model,String mobile) throws ServiceException{
		if(StringUtils.isBlank(mobile)){
			return null;
		}
		DBObject dbusername = apiService.findOneByField(model, Constant.user_phonenum, mobile);
		if (dbusername != null) {
			return dbusername;
		}
		return null;
	}
	/**
	 * 修改用户信息
	 * @param json
	 * @return
	 * @throws ServiceException
	 */
	public JSONObject modify(JSONObject json) throws ServiceException{
		JSONObject user = apiService.get(Constant.model_users, json.getString(Constant.OBJECTID));
		if(!user.containsKey("babyRegisterDate")||StringUtils.isBlank(user.getString("babyRegisterDate"))){
			json.put("babyRegisterDate", DateUtils.SDF3.format(new Date()));//首次注册宝宝时间
		}
		return apiService.update(Constant.model_users, json.toJSONString(), json.getString(Constant.OBJECTID));
	}
	
	
	/**
	 * 修改密码，需要登陆及旧密码
	 * @param userId 用户ＩＤ
	 * @param sessionToken 会话
	 * @param oldPassword 旧密码
	 * @param newPassword 新密码
	 * @return json {objectId//修改成功对象ＩＤ,updatedAt//修改时间}
	 * @throws ServiceException
	 */
	public JSONObject modifyPassword(String userId, String sessionToken, String oldPassword, String newPassword,String site) throws ServiceException {
		JSONObject userQuery = new JSONObject();
		userQuery.put(Constant.OBJECTID, userId);
		userQuery.put(Constant.user_sessionToken, sessionToken);
		userQuery.put(Constant.user_site, site);
		boolean isLogin = authorizationService.auth(Constant.model_users, userQuery);
		if(isLogin){
			JSONObject user = apiService.get(Constant.model_users, userId);
			String salt = user.getString("salt");
			if(StringUtils.isBlank(salt)){
				salt = Constant.sha512_salt;
			}
//			oldPassword = new Sha512Hash(oldPassword, salt, 513).toBase64();

			oldPassword = Md5Util.encode(user.getString(Constant.user_password)+user.getString(Constant.user_username));
			
			if(user!=null && user.getString(Constant.user_password).equals(oldPassword) && StringUtils.isNotBlank(oldPassword)){
//				newPassword = new Sha512Hash(newPassword, salt, 513).toBase64();
				newPassword = Md5Util.encode(newPassword+user.getString(Constant.user_username));
				return modifyPassword(userId, newPassword);
			}
			
		}
		return null;
	}

	/**
	 * 用户密码修改
	 * @param userId 用户ＩＤ
	 * @param newPassword 新密码
	 * @return json {objectId//修改成功对象ＩＤ,updatedAt//修改时间}
	 * @throws ServiceException
	 */
	public JSONObject modifyPassword(String userId,String newPassword) throws ServiceException {
		JSONObject update = new JSONObject();
		update.put(Constant.user_password, newPassword);
		update.put(Constant.user_secretKey, "");
		update.put(Constant.user_sessionToken, "");
		JSONObject tokens = new JSONObject();
		String token = "{sessionToken:'',secretKey:''}";
//		token.put(Constant.user_sessionToken, "");
//		token.put(Constant.user_secretKey, "");
		tokens.put("saas", token);
		tokens.put("h5", token);
//		tokens.put("web", token);
		update.put(Constant.user_tokens, tokens);
		return apiService.update(Constant.model_users, update.toJSONString(), userId);
	}


	/**
	 * 用户详情
	 * @param userId
	 * @return
	 * @throws ServiceException
	 */
	public JSONObject getUserById(String userId) throws ServiceException{
		JSONObject user = apiService.get(Constant.model_users, userId);
		if (user!=null && !user.isEmpty()){
		}else{
			user = new JSONObject();
		}
		return user;
	}
	
	/**
	 * 登陆
	 * @param json
	 * @return 用户基本信息
	 * @throws Exception
	 */
	public JSONObject login(JSONObject json) throws Exception {
		JSONObject jsonObject = authorizationService.login(Constant.model_users, json.toJSONString());
		if(jsonObject == null) {
			return null;
		}
		JSONObject user = getUserById(jsonObject.getString(Constant.OBJECTID));
		JSONObject tokens = jsonObject.getJSONObject(Constant.user_tokens);
		JSONObject toke = tokens.getJSONObject(APPUtils.getTokenSite(json.getString(Constant.user_site)));
		user.put(Constant.user_secretKey, toke.get(Constant.user_secretKey));
		user.put(Constant.user_sessionToken, toke.get(Constant.user_sessionToken));
		return user;
	}
	
	
	/**
	 * 发送手机验证码
	 * @param mobile
	 * @throws Exception
	 */
	public void sendMobleVerifyCode(String mobile) throws Exception {
		verifyCodeService.sendMobileCode(mobile, 120, "105", Constant.saas_saas_app);
	}
	
	/**
	 * 手机验证码较验
	 * @param mobile
	 * @param code
	 * @return
	 * @throws Exception
	 */
	public boolean verifyCode(String mobile, String code) throws ServiceException {
		boolean b = verifyCodeService.verifyMobileCode(mobile, code, Constant.saas_saas_app);
		return b;
	}
	
	/**
	 * 绑定手机号
	 * @param mobile 要绑定手机
	 * @param code 手机验证码
	 * @return
	 * @throws Exception
	 */
	public JSONObject userMobileBind(String userId, String mobile, String code) throws ServiceException,Exception {
		if(this.verifyCode(mobile, code)){
			//绑定该手机号
//			if(!this.mobilePhoneNumberExists(mobile)){
//				return apiService.update(Constant.model_users, "{mobilePhoneNumber:'"+mobile+"'}", userId);
//			}
			//新绑定逻辑-sid
			//1.解绑所有已绑定的当前手机号
			JSONObject query = new JSONObject();
			query.put("mobilePhoneNumber", mobile);
			JSONObject ne = new JSONObject();
			ne.put(MongoCondition.NE.getVal(), userId);
			query.put(Constant.OBJECTID, ne);
			JSONObject users = functionsService.find(query.toJSONString(), "{"+Constant.OBJECTID+":1}", "{}", 
					Constant.model_users, 0, Integer.MAX_VALUE);
			JSONArray list = users.getJSONArray(Constant.RESULTS);
			for (Object object : list) {
				JSONObject one = (JSONObject) object;
				apiService.update(Constant.model_users, "{mobilePhoneNumber:'',mobileIsBind:0}", one.getString(Constant.OBJECTID));
			}
			//2.绑定当前手机号
			JSONObject update = new JSONObject();
			update.put("mobilePhoneNumber", mobile);
			update.put("mobileIsBind", 1);
			return apiService.update(Constant.model_users, update.toJSONString(), userId);
		}else{
			logger.error("请确保手机号和校验输入正确:"+mobile+","+code);
			throw new ServiceException("请确保手机号和校验输入正确");
		}
	}
	
	/**
	 * 
	 * 解绑手机号
	 * userMobileunBind:
	 *
	 * @author sid
	 * @param userId
	 * @param mobile 要解绑手机
	 * @param code 手机验证码
	 * @return
	 * @throws Exception
	 */
	public JSONObject userMobileunBind(String userId, String mobile, String code) throws Exception {
		if(this.verifyCode(mobile, code)){
			JSONObject user = getUserById(userId);
			String userMobile=user.getString("mobilePhoneNumber");
			if(DataUtils.isNotEmpty(userMobile)&&userMobile.equals(mobile)){
				return apiService.update(Constant.model_users, "{mobilePhoneNumber:'',mobileIsBind:0}", userId);
			}
		}
		return null;
	}
	
	public JSONObject resetPwd(String mobile, String code,String pwd) throws Exception {
		if(this.verifyCode(mobile, code)&&StringUtils.isNotBlank(pwd)){
			DBObject user = apiService.findOneByField(Constant.model_users, "mobilePhoneNumber", mobile);
			if(user!=null){
				String salt = user.get("salt") == null ? null : (String)user.get("salt");
				String userId = user.get(Constant.OBJECTID) == null ? null : (String)user.get(Constant.OBJECTID);
				if(StringUtils.isBlank(salt)){
					salt = Constant.sha512_salt;
				}
				pwd = new Sha512Hash(pwd, salt, 513).toBase64();
				pwd = Md5Util.encode(pwd+(String)user.get(Constant.user_username));
				return modifyPassword(userId, pwd);
			}

		}
		return null;
	}
}
